﻿using System;
using System.Data;
using System.Text;
using System.Collections.Generic;
using System.Reflection;
using System.Data.Common;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UtilPublic.ServerLoger;
using System.Web.Script.Serialization;
using UtilLib;

namespace UtilPublic.Serialization
{
    /// <summary>
    /// Json类
    /// </summary>
    public static partial class Jsh
    {
        #region JsonConvert
        /// <summary>
        /// 序列化单个对象
        /// </summary>
        public static string O2J<T>(T obj)
        {
            return JsonConvert.SerializeObject(obj);
        }

        /// <summary> 
        /// 反序列化单个对象
        /// </summary> 
        public static T J2O<T>(string json)
        {
            return JsonConvert.DeserializeObject<T>(json);
        }
        /// <summary>
        /// 反序列化单个对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool J2O<T>(string json, out T obj) where T : new()
        {
            if (!json.IsNullOrEmpty())
            {
                try
                {
                    obj = J2O<T>(json);
                    return true;
                }
                catch { }
            }
            obj = new T();
            return false;
        }

        #endregion

        #region JObject
        /// <summary>
        /// 向 JObject 中添加 object 类型
        /// </summary>
        /// <param name="_jobj">JObject自身</param>
        /// <param name="_name">object需要设置的key</param>
        /// <param name="_obj">object对象</param>
        public static void Add(this JObject _jobj, string _name, object _obj)
        {
            JObject valueObj = new JObject();

            // 避免添加属性自带的私有变量, 还是不要带上私有字段了
            BindingFlags flags = /*BindingFlags.NonPublic |*/ BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static;
            Type type = _obj.GetType();

            FieldInfo[] fields = type.GetFields(flags);                 // 获取字段
            foreach (FieldInfo field in fields)
            {
                valueObj.Add(field.Name, JToken.FromObject(field.GetValue(_obj)));
            }

            PropertyInfo[] properties = type.GetProperties(flags);      // 获取属性
            foreach (PropertyInfo propertie in properties)
            {
                valueObj.Add(propertie.Name, JToken.FromObject(propertie.GetValue(_obj)));
            }

            if (!_jobj.ContainsKey(_name))
                _jobj.Add(_name, valueObj);      // 保证不重复添加
            else
                loger.Debug($"{type.Name} 重复添加");
        }

        /// <summary>
        /// 取出 JObject 中的 object 对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="_jObj">JObject</param>
        /// <param name="_keyName">对象的keyName</param>
        /// <param name="_obj">object对象</param>
        /// <returns></returns>
        public static bool TryGetValue<T>(this JObject _jObj, string _keyName, out T _obj)
        {
            _obj = default;
            // 通过需要的参数类型名, 拿到 _jObj 中相应的 value 
            if (_jObj.TryGetValue(_keyName, out JToken jToken))
            {
                if (typeof(T).IsValueType)
                {
                    _obj = jToken.Value<T>();
                }
                else
                {
                    _obj = jToken.ToObject<T>();
                }
                return true;
            }

            return false;
        }
        #endregion

        #region JavaScriptSerializer
        /// <summary>
        /// 
        /// </summary>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        public static Dictionary<string, object> Deserialize(string jsonString)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Deserialize<Dictionary<string, object>>(jsonString);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string Serialize(Dictionary<string, object> obj)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(obj);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        public static T Deserialize<T>(string jsonString)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Deserialize<T>(jsonString);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string Serialize<T>(T obj)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Serialize(obj);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string TrySerialize<T>(T obj)
        {
            try
            {
                JavaScriptSerializer jss = new JavaScriptSerializer();
                return jss.Serialize(obj);
            }
            catch { }
            return string.Empty;
        }
        #endregion

    }
}